﻿using System;

namespace Mates
{
    public static class Interpolacions
    {
        /// <summary>
        /// Interpolació Catmull-Rom (Cubic Hermite spline)
        /// </summary>
        public static float CatmullRom(float value1, float value2, float value3, float value4, float amount)
        {
            float num = amount * amount;
            float num2 = amount * num;
            return (0.5f * ((((2f * value2) + ((-value1 + value3) * amount)) + (((((2f * value1) - (5f * value2)) + (4f * value3)) - value4) * num)) + ((((-value1 + (3f * value2)) - (3f * value3)) + value4) * num2)));
        }

        /// <summary>
        /// Interpolació Hermite (Cubic Hermite spline)
        /// </summary>
        public static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount)
        {
            float num3 = amount;
            float num = num3 * num3;
            float num2 = num3 * num;
            float num7 = ((2f * num2) - (3f * num)) + 1f;
            float num6 = (-2f * num2) + (3f * num);
            float num5 = (num2 - (2f * num)) + num3;
            float num4 = num2 - num;
            return ((((value1 * num7) + (value2 * num6)) + (tangent1 * num5)) + (tangent2 * num4));
        }
        /// <summary>
        /// Interpolació linear (LERP)
        /// </summary>
        public static float Lerp(float value1, float value2, float amount)
        {
            return (value1 + ((value2 - value1) * amount));
        }
        public static float SmoothStep(float value1, float value2, float amount)
        {
            float num = Funcions.Clamp(amount, 0f, 1f);
            return Lerp(value1, value2, (num * num) * (3f - (2f * num)));
        }
        /// <summary>
        /// IsoSurface Interpolation, ouputs float i float[]. Retorna interpolació entre vector1 i vector2, amb densitats val1 i val2 i minims isoLevel
        /// </summary>
        public static float[] IsoInterpol(float isoLevel, float[] vector1, float[] vector2, float val1, float val2)
        {
            float offset;
            float[] finalPos = new float[3];

            if (Math.Abs(isoLevel - val1) < 0.00001)
                return (vector1);
            if (Math.Abs(isoLevel - val2) < 0.00001)
                return (vector2);
            if (Math.Abs(val1 - val2) < 0.00001)
                return (vector1);

            offset = (isoLevel - val1) / (val2 - val1);
            finalPos[0] = vector1[0] + offset * (vector2[0] - vector1[0]);
            finalPos[1] = vector1[1] + offset * (vector2[1] - vector1[1]);
            finalPos[2] = vector1[2] + offset * (vector2[2] - vector1[2]);

            return finalPos;
        }
        /// <summary>
        /// IsoSurface Interpolation, ouputs float i float[]. Retorna interpolació entre vector1 i vector2, amb densitats val1 i val2 i minims isoLevel
        /// </summary>
        public static float IsoInterpol(float isoLevel, float vector1, float vector2, float val1, float val2)
        {
            float offset;
            float finalPos = 0.0f;

            if (Math.Abs(isoLevel - val1) < 0.00001)
                return (vector1);
            if (Math.Abs(isoLevel - val2) < 0.00001)
                return (vector2);
            if (Math.Abs(val1 - val2) < 0.00001)
                return (vector1);

            offset = (isoLevel - val1) / (val2 - val1);
            finalPos = vector1 + offset * (vector2 - vector1);

            return finalPos;
        }



    }
}
